<?php
namespace core;

class App
{
    /**
     * @var App
     */
    private static $instance;
    /**
     * @var string
     */
    protected $rootPath;
    /**
     * @var Config
     */
    protected $config;
    /**
     * @var string
     */
    protected $pathinfo;

    private function __construct()
    {
        // echo "<br/>+-------------------------------\n";
        // echo "<br/>| App init construct            \n";
        // echo "<br/>+-------------------------------<br/>\n";

        // 设置项目运行根目录
        $this->rootPath = ROOT_PATH;

        // 获取所有配置项
        $this->config = Config::instance()->get();
    }

    /**
     * @author sweeterstar<2021-04-23>
     * @return void
     */
    static public function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new static();
        }
        return self::$instance;
    }

    /**
     * 调度信息
     * @author sweeterstar<2021-04-24>
     * @param array $dispatch 调度信息
     * @return array
     */
    public function dispatch()
    {
        if (!empty(Config::get('app.pathinfo_fetch'))) {
            foreach (Config::get('app.pathinfo_fetch') as $type) {
                if (!empty($_SERVER[$type])) {
                    $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME']))
                        ? substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) 
                        : $_SERVER[$type];
                    break;
                }
            }
        }

        if (!isset($_SERVER['PATH_INFO'])) {
            // TODO ...
        }

        $this->pathinfo = $_SERVER['PATH_INFO'];

        list($module, $controller, $action) = $this->uriParse();

        // 获取控制器命名空间
        $class = '\\app\\controller\\' . $controller;

        /** @var $object Controller */
        $object = new $class($module, $controller, $action);

        // 执行方法
        $object->{$action}();
    }

    /**
     * 解析URL地址：[ /应用名 [ /模块名 [ /控制器 [ /方法名] ] ] ]
     * @return array
     * @author sweeterstar <2021/4/26>
     */
    public function uriParse()
    {
        $uri = trim($this->pathinfo, '/');

        if (Config::get('app.multi_module')) {
            
            // Multi application mode
            list($module, $controller, $action) = explode('/', trim($this->pathinfo, '/'));

        } else {
            // Single application mode
            if (1 < substr_count($uri, '/')) {
                die("[ Error ] Please start multi application mode.");
                // throw new \Exception("Please start multi application mode.", 1);
            }

            list($controller, $action) = explode('/', trim($this->pathinfo, '/'));

            $module = config::get('app.default_module');
        }

        return [$module, $controller, $action];
    }
}